home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_540
/
parm
/
parm_src.lzh
/
ParM.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-28
|
14KB
|
587 lines
/*
* ParM.c - Copyright © 1990 by S.R. & P.C.
*
* Created: 01 Jul 1990
* Modified: 28 Jul 1991 18:25:29
*
* Make>> make
*/
#include "ParMBase.h"
#define COPYRIGHT "ParM V3.0 Copyright © 1990-91 by S.R. & P.C."
#define DEFAULT_CONFIG_FILE "S:ParM.cfg"
#define THE_END 0
#define NO_WIN 10
#define OPEN_ITEM 0
#define UPDATE_ITEM 1
#define STD_CFG_ITEM 2
#define CMDMODE_ITEM 3
#define COMMAND_ITEM 4
#define CHDIR_ITEM 5
#define QUIT_ITEM 6
/* ParM modes */
#define MODE_CLI 0 /* default mode */
#define MODE_WINDOW 1
#define MODE_MYMENU 2
extern void CreateParMenu(short Color);
extern void exit(int);
/***** global variables *****/
extern struct ExecBase *SysBase;
extern struct ParMBase *ParMBase;
extern struct Menu Menu1;
extern struct MenuItem SubItem1;
extern struct WBStartup *WBenchMsg;
/***** local variables *****/
static struct Process *ParMProcess;
static struct Window *Win;
static struct Menu *LastWBMenu, *TheMenu;
static struct MsgPort SwapPort;
static short FirstParMMenuNum; /* = 0 if not attached to WorkBench */
static short ParMMode;
static ULONG OldIDCMP, WinSignal;
static BOOL PortTaken;
static BOOL quit;
static BYTE ParMenuColor = -1;
static struct FileReq FileReq;
static char Dir[REQ_DSIZE+1];
static char File[REQ_FCHARS+1];
static char Path[REQ_DSIZE+REQ_FCHARS+2];
static struct ParMConfig ParMConfig;
static BOOL DoNextSelect;
struct ToolTypesArg {
char *tta_Name;
char tta_cli_equ;
};
static struct ToolTypesArg TTA_List[] = {
{"STACKSIZE", 's'},
{"LEFTEDGE", 'x'},
{"TOPEDGE", 'y'},
{"DETAILPEN", 'd'},
{"BLOCKPEN", 'b'},
{"MENUCOLOR", 'c'},
{"CONFIGFILE", 'f'},
{"NODRAGBAR", 'r'},
{"DEPTHGADGETS",'g'},
{"NOAUTOFRONT", 'a'},
{"MYMENU", 'm'}
};
#define TTANUM 11 /* Number of ToolTypesArg in List */
static struct NewWindow NWS = {
0, 0, /* window XY origin relative to TopLeft of screen */
39, 10, /* window width and height */
3, 2, /* detail and block pens */
MENUPICK|RAWKEY|REFRESHWINDOW, /* IDCMP flags */
WINDOWDRAG|SIMPLE_REFRESH, /* other window flags */
NULL, /* first gadget in gadget list */
NULL, /* custom CHECKMARK imagery */
(UBYTE *)"ParM", /* window title */
NULL, /* custom screen pointer */
NULL, /* custom bitmap */
5, 5, /* minimum width and height */
-1, -1, /* maximum width and height */
WBENCHSCREEN /* destination screen type */
};
static struct Window *FindWorkBench(void)
{
struct Screen *WBS;
struct Window *WBW = NULL;
ULONG ilock;
if (WBS = OpenWorkBench()) {
ilock = LockIBase(0L); /* Just so's things don't change on us */
WBW = WBS->FirstWindow;
while (WBW) {
/* Only main WB Window has NEWPREFS IDCMPFlag set, so find it */
if ((WBW->Flags & WBENCHWINDOW) && (WBW->IDCMPFlags & NEWPREFS)) {
TheMenu = WBW->MenuStrip;
LastWBMenu = TheMenu->NextMenu->NextMenu;
FirstParMMenuNum = 3;
break;
}
WBW = WBW->NextWindow;
}
UnlockIBase(ilock);
}
return WBW;
}
void TakeMsgPort(void)
{
struct MsgPort *WinPort;
struct List *myMsgList = &(SwapPort.mp_MsgList);
struct List *winMsgList;
SwapPort.mp_Node.ln_Type = NT_MSGPORT;
SwapPort.mp_Flags = PA_SIGNAL;
Forbid();
/* get the info we need */
WinPort = Win->UserPort;
winMsgList = &(WinPort->mp_MsgList);
/* setup our port */
SwapPort.mp_SigBit = WinPort->mp_SigBit;
SwapPort.mp_SigTask = WinPort->mp_SigTask;
/* flip things around */
WinPort->mp_SigTask = (struct Task *)ParMProcess;
/* Prevent signal for being allocated later */
WinSignal = AllocSignal(WinPort->mp_SigBit);
myMsgList->lh_Head = (struct Node *) &winMsgList->lh_Tail;
myMsgList->lh_TailPred = winMsgList->lh_TailPred;
winMsgList->lh_TailPred = (struct Node *) &myMsgList->lh_Head;
myMsgList->lh_TailPred->ln_Succ = (struct Node *) &myMsgList->lh_Tail;
Permit();
/* prevent deadlocks */
SetTaskPri((struct Task *)ParMProcess, SwapPort.mp_SigTask->tc_Node.ln_Pri + 1);
}
/* Restore things the way they were before TakeMsgPort() */
void DelMsgPort(void)
{
struct Message *Msg;
struct List *myMsgList = &(SwapPort.mp_MsgList);
Forbid();
/* clean out our list */
while (Msg = GetMsg(&SwapPort))
PutMsg(&SwapPort, Msg);
/* restore things */
myMsgList->lh_Head->ln_Pred = myMsgList->lh_TailPred;
myMsgList->lh_TailPred->ln_Succ = myMsgList->lh_Head;
Win->UserPort->mp_SigTask = SwapPort.mp_SigTask;
if (WinSignal)
FreeSignal(WinSignal);
Permit();
}
/* Configuration managing functions */
static void InstallWBMenus(struct Menu *Menus)
{
long ilock;
ilock = LockIBase(0);
ClearMenuStrip(Win);
if (Menus)
CleanUp(TheMenu, 0, ParMConfig.ItemHeight);
LastWBMenu->NextMenu = Menus;
SetMenuStrip(Win, TheMenu);
UnlockIBase(ilock);
}
static void ClearMenus(void)
{
if (ParMMode == MODE_MYMENU) {
InstallWBMenus(NULL);
Menu1.LeftEdge = LastWBMenu->LeftEdge + LastWBMenu->Width;
}
else
ClearMenuStrip(Win);
}
void UpDateMenus(void)
{
ClearMenus();
ParMConfig.MenuPen = ParMenuColor;
if (!ParseMenus(&ParMConfig))
FreeMenus(&ParMConfig);
if (ParMMode == MODE_MYMENU)
InstallWBMenus(&Menu1);
else
SetMenuStrip(Win, &Menu1);
}
static void OpenMenus(void)
{
char *yuck;
FileReq.Title = "Open";
strcpy(Dir, ParMConfig.CurCfg);
strcpy(File, yuck = BaseName(Dir));
*yuck = '\0'; /* cut off filename from fr_Dir */
if (!FileRequester(&FileReq))
return; /* quit if Open canceled */
strcpy(ParMConfig.CurCfg, Path);
UpDateMenus();
}
/* Print busy message in place of window title */
static void Busy(BOOL status)
{
SetWindowTitles(Win, (status) ? "Busy" : "ParM", COPYRIGHT);
}
static void Usage(void)
{
Printf("%s\nUsage: ParM [-m] [-w] [-x#] [-y#] [-d#] [-b#] [-c#] [-r] [-g] [-a] [-o] [-s#] [-fConfigFile]\n", COPYRIGHT);
exit(0);
}
/* Atcho, bonsoir... */
void Bye(short err)
{
if (err == THE_END) {
ClearMenus();
FreeMenus(&ParMConfig);
if (PortTaken)
DelMsgPort();
if (ParMMode == MODE_CLI)
ModifyIDCMP(Win, OldIDCMP);
else if (ParMMode == MODE_WINDOW)
CloseWindowSafely(Win, NULL);
}
exit(err);
}
/* change parm current directory */
static void ChangeDir(char *dir)
{
BPTR NewLock, OldLock;
NewLock = Lock(dir, ACCESS_READ);
if (NewLock != NULL) {
OldLock = CurrentDir(NewLock);
if (OldLock != NULL)
UnLock(OldLock);
}
}
static void DoExtMenu(USHORT MenuNum)
{
struct Extended_MenuItem *Item;
struct Extended_WBStartup *EWBS;
Item = (struct Extended_MenuItem *)ItemAddress(TheMenu, MenuNum);
switch (Item->emi_Mode) {
case TOK_ARUN:
ARun(&ParMConfig, &Item->emi_RunInfo);
break;
case TOK_RUN:
case TOK_SHELL:
Run(&ParMConfig, &Item->emi_RunInfo, Item->emi_Mode);
break;
case TOK_WB:
if (EWBS = MakeWBStartup(&ParMConfig, &Item->emi_RunInfo))
WBRun(&ParMConfig, EWBS, Item->emi_RunInfo.ri_Pri);
break;
case TOK_CFG: /* new cfg */
strcpy(ParMConfig.CurCfg, Item->emi_RunInfo.ri_Cmd);
UpDateMenus();
DoNextSelect = FALSE; /* Tell DoIntuiMsg not to execute next menu selection */
}
}
static void parse_arg(char opt, char *args)
{
BPTR fh;
long argl;
argl = Atol(args);
switch (opt) {
case 'm':
ParMMode = MODE_MYMENU;
break;
case 'w':
ParMMode = MODE_WINDOW;
break;
case 's':
if (argl >= 4000) ParMConfig.DefaultStack = argl;
break;
case 'x':
NWS.LeftEdge = argl;
ParMMode = MODE_WINDOW;
break;
case 'y':
NWS.TopEdge = argl;
ParMMode = MODE_WINDOW;
break;
case 'd':
NWS.DetailPen = argl;
ParMMode = MODE_WINDOW;
break;
case 'b':
NWS.BlockPen = argl;
ParMMode = MODE_WINDOW;
break;
case 'c':
ParMenuColor = argl;
break;
case 'f':
strcpy(ParMConfig.CurCfg, args);
break;
case 'r': /* no drag bar */
ParMMode = MODE_WINDOW;
NWS.Flags &= ~WINDOWDRAG;
break;
case 'g': /* depth gadgets */
ParMMode = MODE_WINDOW;
NWS.Flags |= WINDOWDEPTH;
NWS.Width += 51;
break;
case 'a':
ParMMode = MODE_WINDOW;
NWS.Flags |= NOCAREREFRESH;
break;
case 'o':
if ((fh = Open("NULL:", MODE_NEWFILE)) || (fh = Open("NIL:", MODE_NEWFILE))) {
ParMProcess->pr_CIS = fh;
ParMProcess->pr_COS = fh;
ParMProcess->pr_ConsoleTask = (APTR)((struct FileHandle *)(fh<<2))->fh_Type;
}
break;
case 'h': /* those can only happen on CLI invocation */
default:
Usage();
}
}
void main(int argc, char *argv[])
{
struct CommandLineInterface *cli;
struct DiskObject *dop;
struct MsgPort *WorkPort;
struct IntuiMessage *IMsg;
ULONG Class;
USHORT Code,Qual;
BOOL RefreshIt = TRUE;
char *arg;
short i;
TheMenu = &Menu1;
InitDefaults(&ParMConfig);
ParMConfig.ReqTitle = "ParM Request";
ParMConfig.LinkMenu = &Menu1;
ParMConfig.ItemHeight = 10; /* 9 in BrowserII */
ParMConfig.SimpleCmdMode = TRUE;
FileReq.Dir = Dir;
FileReq.File = File;
FileReq.PathName = Path;
FileReq.dirnamescolor = 3;
FileReq.devicenamescolor = 3;
FileReq.stringnamecolor = 2;
FileReq.stringgadgetcolor = 2;
FileReq.boxbordercolor = 2;
FileReq.gadgetboxcolor = 2;
strcpy(FileReq.Show, "*.cfg");
ParMProcess = (struct Process *)SysBase->ThisTask;
strcpy(ParMConfig.CurCfg, DEFAULT_CONFIG_FILE);
if (WBenchMsg) { /* Tool Types parsing */
ParMMode == MODE_WINDOW; /* may be latter overridden by MYMENU mode */
if (dop = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)) {
ParMConfig.DefaultStack = dop->do_StackSize;
for( i = 0 ; i < TTANUM ; i++ ) {
if (arg = FindToolType(dop->do_ToolTypes, TTA_List[i].tta_Name))
parse_arg(TTA_List[i].tta_cli_equ, arg);
}
FreeDiskObject(dop);
}
parse_arg('o', ""); /* allways redirect output to NULL: if started from WorkBench */
}
else { /* CLI parsing */
cli = (struct CommandLineInterface *)((long)ParMProcess->pr_CLI << 2);
ParMConfig.DefaultStack = cli->cli_DefaultStack << 2;
for( i = 0 ; i < argc ; i++ ) {
if (*argv[i] != '-' || strlen(argv[i]) < 2)
Usage();
parse_arg(argv[i][1], &argv[i][2]);
}
}
switch(ParMMode) {
case MODE_WINDOW:
if (!(Win = OpenWindow(&NWS)))
Bye(NO_WIN);
Busy(FALSE); /* SetWindowTitles() */
break;
case MODE_CLI:
Win = GetWindow();
if (Win->UserPort) {
if (Win->IDCMPFlags & MENUPICK) {
SimpleRequest(ParMConfig.ReqTitle, "This window already have menus.");
Bye(NO_WIN);
}
else {
PortTaken = TRUE;
OldIDCMP = Win->IDCMPFlags;
}
}
ModifyIDCMP(Win, Win->IDCMPFlags|MENUPICK|CLOSEWINDOW);
break;
case MODE_MYMENU:
if (Win = FindWorkBench()) {
if (LastWBMenu->NextMenu) {
SimpleRequest(ParMConfig.ReqTitle, "Menus already installed in WorkBench.");
Bye(NO_WIN);
}
else
PortTaken = TRUE;
}
else {
SimpleRequest(ParMConfig.ReqTitle, "Can't find WorkBench.");
Bye(NO_WIN);
}
}
ParMConfig.Win = Win;
if (PortTaken)
TakeMsgPort();
if (ParMenuColor < 0) ParMenuColor = Win->DetailPen;
CreateParMenu(ParMenuColor);
UpDateMenus();
/* Monitor Menu Events */
WorkPort = (PortTaken) ? &SwapPort : Win->UserPort;
while (!quit) {
WaitPort(WorkPort);
while (IMsg = (struct IntuiMessage *)GetMsg(WorkPort)) {
Class = IMsg->Class;
Code = IMsg->Code;
Qual = IMsg->Qualifier;
/* Use raw keys to prevent ALT and CTRL convertions. Allow only Shift qualifiers */
if (Class == RAWKEY) {
Code = RawKeyToAscii(Code, Qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT), IMsg->IAddress);
if (Code != 0 && (Qual & ParMConfig.ShortCutQual) && !(Qual & IEQUALIFIER_REPEAT)) {
Code = MakeMenuShortCut(TheMenu, Code);
Class = MENUPICK;
}
}
/*
* PutMsg() conditions (Messages given to port monitored):
* MODE_WINDOW:
* No such port, so all messages replied.
* MODE_MYMENU:
* give all messages but ParM's menus MENUPICK and RAWKEYs converted
* to MENUPICK. handle NEWPREFS after PutMsg().
* MODE_CLI:
* if PortTaken, all but MENUPICK and CLOSEWINDOW.
*/
if (!PortTaken
|| (Class == MENUPICK && (MENUNUM(Code) >= FirstParMMenuNum))
|| (ParMMode == MODE_CLI && Class == CLOSEWINDOW))
{
if (Class == 0x0FL) /* Msg sent bye 'ParMCD' command */
ChangeDir((char *)IMsg->IAddress);
ReplyMsg((struct Message *)IMsg);
}
else {
PutMsg(&SwapPort, (struct Message *)IMsg);
if (Class == NEWPREFS) {
while (LastWBMenu->NextMenu)
Delay(10);
InstallWBMenus(&Menu1);
}
continue; /* Don't handle these messages */
}
switch (Class) {
case CLOSEWINDOW:
quit = TRUE;
break;
case REFRESHWINDOW:
if (RefreshIt) {
if (IsHidden(Win)) {
WindowToFront(Win);
RefreshIt = FALSE; /* prevent refresh caused by WindoToFront() */
}
}
else
RefreshIt = TRUE;
break;
case MENUPICK:
DoNextSelect = TRUE;
if (Code != MENUNULL) {
if (ParMMode == MODE_WINDOW)
Busy(TRUE);
do {
/* Prevent extended selection of workbench menus */
if (MENUNUM(Code) == FirstParMMenuNum) {
switch(ITEMNUM(Code)) {
case OPEN_ITEM:
OpenMenus();
DoNextSelect = FALSE;
break;
case UPDATE_ITEM:
UpDateMenus();
DoNextSelect = FALSE;
break;
case STD_CFG_ITEM:
strcpy(ParMConfig.CurCfg, DEFAULT_CONFIG_FILE);
UpDateMenus();
DoNextSelect = FALSE;
break;
case CMDMODE_ITEM:
ParMConfig.SimpleCmdMode = SubItem1.Flags & CHECKED;
break;
case COMMAND_ITEM:
Command(&ParMConfig);
break;
case CHDIR_ITEM:
PathName(ParMProcess->pr_CurrentDir, Dir, REQ_DSIZE);
FileReq.Flags = FRQDIRONLYM;
FileReq.Title = "Enter New Dir...";
if (FileRequester(&FileReq))
ChangeDir(Dir);
FileReq.Flags = 0;
break;
case QUIT_ITEM:
quit = TRUE;
DoNextSelect = FALSE;
}
}
else if (MENUNUM(Code) > FirstParMMenuNum) /* custom menus */
DoExtMenu(Code);
} while (DoNextSelect && (Code = ItemAddress(TheMenu, Code)->NextSelect) != MENUNULL);
if (ParMMode == MODE_WINDOW)
Busy(FALSE);
}
break;
}
}
/* See if some wb messages have been replied, and free them */
FreeRepliedWBMessages();
}
Bye(THE_END);
}